/**
 * JSX 类型支持
 *
 * 提供 TypeScript JSX 完整类型定义，支持静态类型检查和智能提示
 * 扩展全局 JSX 命名空间，定义可用的元素和属性类型
 */

import { ReactElement } from "./createElement";

// 扩展全局 JSX 命名空间
declare global {
  // TypeScript 的 JSX 命名空间
  namespace JSX {
    // 定义可以在 JSX 中使用的内置元素类型
    interface IntrinsicElements {
      // 基础容器元素
      box: Element<UiBox>;

      // 文本显示元素
      text: Element<UiText>;

      // 滚动框元素
      scrollBox: Element<UiScrollBox>;

      // 输入控件元素，包括焦点事件支持
      input: Element<UiInput> & {
        /** 获得焦点事件处理器 */
        onFocus?: (event: UiEvent<UiInput>) => void;
        /** 失去焦点事件处理器 */
        onBlur?: (event: UiEvent<UiInput>) => void;
      };

      // 图像元素，支持加载事件
      image: Element<UiImage> & {
        /** 图片加载完成事件处理器 */
        onLoad?: (event: UiEvent<UiImage>) => void;
      };
    }

    // 定义所有元素共有的属性和事件
    interface Element<T> extends Omit<ReactElement, "children"> {
      /**
       * 元素唯一标识名称
       * 用于在UI元素管理器中查找和控制元素
       */
      name?: string;

      /**
       * 样式对象，定义元素的视觉外观
       */
      style?: Omit<Partial<T>, "position" | "size"> & {
        /** 位置配置 */
        position?: {
          /** X/Y偏移量 */
          offset?: Vec2;
          /** 宽高缩放比例 */
          size?: Vec2;
        };
        /** 尺寸配置 */
        size?: {
          /** 尺寸偏移量 */
          offset?: Vec2;
          /** 尺寸缩放比例 */
          size?: Vec2;
        };
      };

      /** 子元素内容 */
      children?: any;

      /** 点击事件处理器 */
      onClick?: (event: UiEvent<T>) => void;
      /** 鼠标按下事件处理器 */
      onMouseDown?: (event: UiEvent<T>) => void;
      /** 鼠标释放事件处理器 */
      onMouseUp?: (event: UiEvent<T>) => void;

      /** 元素挂载完成回调 */
      onMount?: (element: T) => void;
      /** 元素卸载前回调 */
      onUnmount?: (element: T) => void;
      /** 元素引用，获取底层DOM实例 */
      ref?: ((element: T) => void) | { current: T | null };
    }

    // 组件属性类型定义属性
    interface ElementAttributesProperty {
      props: {};
    }

    // 子元素属性类型定义
    interface ElementChildrenAttribute {
      children: {};
    }
  }
}

/**
 * 引用对象接口
 * 允许组件保存和操作DOM元素引用
 */
export interface RefObject<T> {
  current: T | null;
}
